package com.victualler.core.common.utils;


import com.victualler.core.base.dao.BaseDao;
import com.victualler.core.common.annotation.SimpleQueryFrom;
import com.victualler.core.common.annotation.SimpleQueryOrderBy;
import com.victualler.core.common.annotation.SimpleQuerySelect;
import com.victualler.core.common.annotation.SimpleQueryWhere;
import com.victualler.core.common.dto.PageDto;
import com.victualler.core.common.dto.SimpleQueryObjectVO;
import com.victualler.core.common.enums.QueryType;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TemporalType;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Aouthor Guoshichang   
 * @Date 20:05 on 2018/5/28.
 * @Function 将出入参数配置转换为hql语句的工具类
 */
public class HQLConverterUtil {


	/**
	 * @Aouthor Guoshichang
	 * @Date 21:09 on 2018/5/28.
	 * @param requestVO 入参对象
	 * @param pageNo 分页页码 --1开始
	 * @param limit 每页长度
	 * @param entityManager JPA持久化工具类
	 * @Function 根据入参查询对应对象RequestVO 进行分页查询
	 */
	public static <T> PageDto<T> findPageByRequestVO(Object requestVO, Class<T> responseVO, int pageNo, int limit, EntityManager entityManager) throws Exception {
		//转换sql查询对象
		SimpleQueryObjectVO queryObject = HQLConverterUtil.convertToSimpleQueryObject(requestVO, responseVO);
		//统计总条数
		long  count = HQLConverterUtil.getCountBySql(queryObject, entityManager);
		//设置分页//分页查询
		queryObject.setPageNo(pageNo);
		queryObject.setLimit(limit);
		List<T> facAccountResponseVOList = HQLConverterUtil.getListBySql(queryObject, entityManager, responseVO);
		//转换为Pagination对象
		return new PageDto(facAccountResponseVOList,pageNo,limit,count);
	}


	/**
	 * @Aouthor Guoshichang
	 * @Date 21:09 on 2018/5/28.
	 * @param requestVO 入参对象
	 * @param entityManager JPA持久化工具类
	 * @Function 根据账单查询对应对象facAccountRequestVO 进行分页查询
	 */
	public static <T>PageDto<T>  findEOPageByRequestVO(Object requestVO, Class<? extends BaseDao> responseEOClass,int pageNo ,int limit, EntityManager entityManager) throws Exception {
		//转换sql查询对象
		SimpleQueryObjectVO queryObject = new SimpleQueryObjectVO();
		queryObject.getSelectString().append("SELECT ").append(responseEOClass.getSimpleName()).append(".* ");
		queryObject = HQLConverterUtil.getFromAndWhereBody(queryObject,requestVO,responseEOClass);
		String  sql = queryObject.toSql();
		System.out.println(sql);
		//计算总数
		long  count = HQLConverterUtil.getCountByRequestVO(requestVO,responseEOClass,entityManager);
		//设置分页//分页查询
		int start = (pageNo-1)*limit;
		int end = limit;
		//插入分页查询
		sql += "  limit   "+start+" , "+end+" ";

		Query query = entityManager.createNativeQuery(sql, responseEOClass);
		HQLConverterUtil.setParamsByMap(queryObject.getWhereValueMap(),query);
		List<T> result = query.getResultList();
		//转换为Pagination对象
		return new PageDto(result,pageNo,limit,count);
	}


	/**
	 * @Aouthor Guoshichang
	 * @Date 21:09 on 2018/5/28.
	 * @param sql sql语句
	 * @param params 参数列表
	 * @param responseEOClass 返回对象
	 * @param pageNo 查询页码 从1开始
	 * @param limit 每页长度
	 * @param entityManager JPA持久化工具类
	 * @Function 根据入参查询对应对象RequestVO 进行分页查询
	 */
	public static <T> PageDto<T> findPageBySql(String sql,Object[] params,Class<?> responseEOClass,int pageNo, int limit,EntityManager entityManager) throws Exception {
		//转换sql查询对象
		//统计总条数
		long  count = HQLConverterUtil.getCountBySql(sql,params, entityManager);
		//设置分页//分页查询
		int start = (pageNo-1)*limit;
		int end = limit;
		//插入分页查询
		sql += "  limit   "+start+" , "+end+" ";
		List<T>  responseVOList = HQLConverterUtil.findVOListBySql(sql,params, responseEOClass,entityManager);
		//转换为Pagination对象
		return new PageDto(responseVOList,pageNo,limit,count);
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 21:09 on 2018/5/28.
	 * @param sql sql语句
	 * @param params 参数列表
	 * @param responseEOClass 返回对象
	 * @param pageNo 查询页码 从1开始
	 * @param limit 每页长度
	 * @param entityManager JPA持久化工具类
	 * @Function 根据入参查询对应对象RequestVO 进行分页查询
	 */
	public static <T> PageDto<T> findPageBySql(String sql,Map<String,Object> params,Class<?> responseEOClass,int pageNo, int limit,EntityManager entityManager) throws Exception {
		//转换sql查询对象
		//统计总条数
		long  count = HQLConverterUtil.getCountBySql(sql,params, entityManager);
		//设置分页//分页查询
		int start = (pageNo-1)*limit;
		int end = limit;
		//插入分页查询
		sql += "  limit   "+start+" , "+end+" ";
		List<T>  responseVOList = HQLConverterUtil.findVOListBySql(sql,params, responseEOClass,entityManager);
		//转换为Pagination对象
		return new PageDto(responseVOList,pageNo,limit,count);
	}


	/**
	 * @Aouthor Guoshichang
	 * @Date 21:09 on 2018/5/28.
	 * @param requestVO 入参对象
	 * @param entityManager JPA持久化工具类
	 * @Function 根据账单查询对应对象facAccountRequestVO 进行分页查询
	 */
	public static <T>List<T>  findByRequestVO(Object requestVO,Class<T> responseVO,EntityManager entityManager) throws Exception {
		//转换sql查询对象
		SimpleQueryObjectVO queryObject = HQLConverterUtil.convertToSimpleQueryObject(requestVO, responseVO);
		return  HQLConverterUtil.getListBySql(queryObject, entityManager, responseVO);
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 21:09 on 2018/5/28.
	 * @param requestVO 入参对象
	 * @param entityManager JPA持久化工具类
	 * @Function 根据账单查询对应对象facAccountRequestVO 进行分页查询
	 */
	public static <T>List<T>  findEOListByRequestVO(Object requestVO, Class<? extends BaseDao> responseEOClass, EntityManager entityManager) throws Exception {
		//转换sql查询对象
		SimpleQueryObjectVO queryObject = new SimpleQueryObjectVO();
		queryObject.getSelectString().append("SELECT ").append(responseEOClass.getSimpleName()).append(".* ");
		queryObject = HQLConverterUtil.getFromAndWhereBody(queryObject,requestVO,responseEOClass);
		String  sql = queryObject.toSql();

		Query query = entityManager.createNativeQuery(sql, responseEOClass);
		HQLConverterUtil.setParamsByMap(queryObject.getWhereValueMap(),query);
		List<T> result = query.getResultList();
		return  result;
	}

	/**
	 * @author Guoshichang
	 * @date 11:31 on 2018/6/27.
	 * @param requestVO 注解配置查询对象
	 * @function 根据查询对象count查询结果
	 */
	public static long getCountByRequestVO(Object requestVO, Class<? extends BaseDao> responseEOClass, EntityManager entityManager) throws Exception {
		SimpleQueryObjectVO queryObject = new SimpleQueryObjectVO();
		queryObject.getSelectString().append("SELECT ").append(responseEOClass.getSimpleName()).append(".* ");
		queryObject = HQLConverterUtil.getFromAndWhereBody(queryObject,requestVO,responseEOClass);
		String  sql = queryObject.toSql();
		//查询
		StringBuffer countSql= new StringBuffer("select count(*) from (") .append(sql) .append(") temp");
		Query query = entityManager.createNativeQuery(countSql.toString());
		//设置参数
		HQLConverterUtil.setParamsByMap(queryObject.getWhereValueMap(),query);
		if(query.getSingleResult() instanceof BigDecimal){
			return ((BigDecimal)query.getSingleResult()).longValue();
		}else{
			return ((BigInteger)query.getSingleResult()).longValue();
		}

	}


	/**
	 * @Aouthor Guoshichang
	 * @Date 15:52 on 2018/6/11.
	 * @param sql  原生sql
	 * @param params sql 中对应的参数
	 * @param responseEOClass 返回参数的class
	 * @param entityManager jpa 对应的执行工具类
	 * @Function 根据某个固定条件的sql查询实体列表
	 */
	public static <T>List<T>  findEOListBySql(String sql,Object[] params, Class<? extends BaseDao> responseEOClass, EntityManager entityManager) throws Exception {
		Query query = entityManager.createNativeQuery(sql, responseEOClass);
		HQLConverterUtil.setParamsByObjectArray(params, query);
		List<T> result = query.getResultList();
		return  result;
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 15:52 on 2018/6/11.
	 * @param sql
	 *            原生sql
	 * @param params
	 *            sql 中对应的参数
	 * @param responseEOClass
	 *            返回参数的class
	 * @param entityManager
	 *            jpa 对应的执行工具类
	 * @param <T>
	 *            泛型
	 * @return List
	 * @Function 根据某个固定条件的sql查询实体列表
	 */
	public static <T> List<T> findEOListBySql(String sql, Map<String, Object> params,
											  Class<? extends BaseDao> responseEOClass, EntityManager entityManager) throws Exception {
		Query query = entityManager.createNativeQuery(sql, responseEOClass);
		HQLConverterUtil.setParamsByMap(params, query);
		List<T> result = query.getResultList();
		return result;
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 15:52 on 2018/6/11.
	 * @param sql
	 *            原生sql
	 * @param params
	 *            sql 中对应的参数
	 * @param responseVOClass
	 *            返回参数的class
	 * @param entityManager
	 *            jpa 对应的执行工具类
	 * @param <T>
	 *            泛型
	 * @return List
	 * @Function 根据某个固定条件的sql查询实体列表
	 * @throws Exception
	 *             异常
	 */
	public static <T> List<T> findVOListBySql(String sql, Object[] params, Class<?> responseVOClass,
											  EntityManager entityManager) throws Exception {
		List<T> result = new ArrayList<>();
		Query query = entityManager.createNativeQuery(sql);
		HQLConverterUtil.setParamsByObjectArray(params, query);
		// 负责将查询结果集转换到VO对象中
		return HQLConverterUtil.getQueryList(query, responseVOClass);
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 15:52 on 2018/6/11.
	 * @param sql
	 *            原生sql
	 * @param params
	 *            sql 中对应的参数
	 * @param responseVOClass
	 *            返回参数的class
	 * @param entityManager
	 *            jpa 对应的执行工具类
	 * @param <T>
	 *            泛型
	 * @return List
	 * @Function 根据某个固定条件的sql查询实体列表
	 */
	public static <T> List<T> findVOListBySql(String sql, Map<String, Object> params, Class<?> responseVOClass,
											  EntityManager entityManager) throws Exception {
		List<T> result = new ArrayList<>();
		Query query = entityManager.createNativeQuery(sql);
		HQLConverterUtil.setParamsByMap(params, query);
		// 负责将查询结果集转换到VO对象中
		return HQLConverterUtil.getQueryList(query, responseVOClass);
	}

	/**
	 * @author Guoshichang
	 * @since 19:50 on 2018/7/19.
	 * @param requestObject
	 *            查询对象
	 * @return Map
	 * @Function 将对象中非空的字段转换为map 便于封装查询条件
	 */
	public static Map<String, Object> getRequestParams(Object requestObject) throws Exception {
		Map<String, Object> paramMap = new HashMap<>();
		for (Field field : requestObject.getClass().getDeclaredFields()) {
			field.setAccessible(true);
			Object value = field.get(requestObject);
			if (value != null) {
				paramMap.put(field.getName(), value);
			}
		}
		return paramMap;
	}



	/**
	 * @author Guoshichang
	 * @since 10:17 on 2018/7/30.
	 * @param query
	 *            JPA查询对象
	 * @param responseVOClass
	 *            返回参数类型
	 * @param <T>
	 *            泛型
	 * @return List
	 * @Function 负责将查询结果集转换到VO对象中
	 */
	private static <T> List<T> getQueryList(Query query, Class<?> responseVOClass)
			throws IllegalAccessException, InstantiationException {
		query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		// 取出列
		List<Map<String, Object>> list = query.getResultList();
		List<T> resultList = new ArrayList<>();
		for (Map<String, Object> map : list) {
			Object object = responseVOClass.newInstance();
			for (String fieldName : map.keySet()) {
				Object columnValue = map.get(fieldName); // 值
				// 匹配字段
				Field field = getFieldByLowerCase(fieldName.replace("_",""), responseVOClass);
				Class wileClass = responseVOClass;
				while (field == null && !wileClass.getSuperclass().getName().endsWith("Object")) {
					wileClass = wileClass.getSuperclass();
					//尝试从父类找一遍
					field = getFieldByLowerCase(fieldName.replace("_",""), wileClass);
				}
				if (field == null) {
					continue;
				}
				field.setAccessible(true);
				// BigDecimal类型转换
				columnValue = HQLConverterUtil.bigDecimalAdapter(columnValue, field);
				field.set(object, columnValue);
			}
			resultList.add((T) object);
		}
		// 反馈
		return resultList;
	}


	/**
	 * @author Guoshichang
	 * @since 14:50 on 2018/7/20.
	 * @param columName
	 *            待匹配的列名
	 * @param responseVOClass
	 *            带匹配的类型
	 * @return Field
	 * @Function 根据小写字符匹配对象对应的字段, 若有符合则返回
	 */
	private static Field getFieldByLowerCase(String columName, Class<?> responseVOClass) {
		// 匹配对象中的字段
		for (Field field : responseVOClass.getDeclaredFields()) {
			field.setAccessible(true);
			// 按照小写去匹配字段名
			if (field.getName().toLowerCase().equals(columName.toLowerCase())) {
				return field;
			}
		}
		return null;
	}


	/**
	 * @Aouthor Guoshichang
	 * @Date 20:50 on 2018/5/28.
	 * @param sql 查询对象
	 * @param entityManager herbinate查询器
	 * @Function 根据queryObject 查询总条数
	 */
	public static long getCountBySql(String sql,Object[] params, EntityManager entityManager){
		//查询
		StringBuffer countSql= new StringBuffer("select count(*) from (") .append(sql) .append(") temp");
		Query query = entityManager.createNativeQuery(countSql.toString());
		HQLConverterUtil.setParamsByObjectArray(params,query);
		return ((BigInteger)query.getSingleResult()).longValue();
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 20:50 on 2018/5/28.
	 * @param sql 查询对象
	 * @param entityManager herbinate查询器
	 * @Function 根据queryObject 查询总条数
	 */
	public static long getCountBySql(String sql,Map<String,Object> params, EntityManager entityManager){
		//查询
		StringBuffer countSql= new StringBuffer("select count(*) from (") .append(sql) .append(") temp");
		Query query = entityManager.createNativeQuery(countSql.toString());
		HQLConverterUtil.setParamsByMap(params,query);
		return ((BigInteger)query.getSingleResult()).longValue();
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 19:29 on 2018/5/29.
	 * @param paramObject 入参对象
	 * @param resultListClass 出参类型
	 * @Function 根据入参对象 和 出参的类型 获取对应的出参查询对象
	 */
	private static  SimpleQueryObjectVO convertToSimpleQueryObject(Object paramObject,Class<?> resultListClass) throws Exception{
		SimpleQueryObjectVO simpleQueryObjectVO= new SimpleQueryObjectVO();
		//获得where部分
		HQLConverterUtil.getSelectBody(simpleQueryObjectVO,resultListClass);
		//获得from部分
		HQLConverterUtil.getFromAndWhereBody(simpleQueryObjectVO, paramObject, resultListClass);
		
		return simpleQueryObjectVO;
	}


	/**
	 * @Aouthor Guoshichang
	 * @Date 20:50 on 2018/5/28.
	 * @param queryObject 查询对象
	 * @param entityManager herbinate查询器
	 * @param resultListClass 返参类型
	 * @Function 根据queryObject 查询分页对象
	 */
	private  static <T> List<T> getListBySql(SimpleQueryObjectVO queryObject, EntityManager entityManager, Class<T> resultListClass) throws Exception{
		//加入分页 条件
		if(queryObject.getPageNo()!=-1 && queryObject.getLimit()!=-1){
			int start = (queryObject.getPageNo()-1)*queryObject.getLimit();
			int end = queryObject.getLimit();
			queryObject.getWhereString().append("   limit   ");
			queryObject.getWhereString().append(" ").append(start) ;
			queryObject.getWhereString().append(" ").append(",").append(" ");
			queryObject.getWhereString().append(" ").append(end).append(" ");
		}
		//生成sql
		String sql = queryObject.toSql();
		//查询
		Query query = entityManager.createNativeQuery(sql);
		HQLConverterUtil.setParamsByMap(queryObject.getWhereValueMap(),query);
		//映射设置结果
		List<T> resultList = new ArrayList<>();
		List<Object[]> list = query.getResultList();
		List<String> fields = queryObject.getSelectField();//查询字段
		for (Object[] objects:list) {
			Object  object = resultListClass.newInstance();
			//映射类字段
			for (int i=0; i<objects.length;i++) {
				Object columnValue=objects[i];
				String columnName=fields.get(i);
				Field field = resultListClass.getDeclaredField(columnName);
				field.setAccessible(true);
				//BigDecimal类型转换
				columnValue = HQLConverterUtil.bigDecimalAdapter(columnValue,field);
				field.set(object,columnValue);
			}
			resultList.add((T)object);
		}
		//反馈
		return resultList;
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 20:50 on 2018/5/28.
	 * @param queryObject 查询对象
	 * @param entityManager herbinate查询器
	 * @Function 根据queryObject 查询总条数
	 */
	private static long getCountBySql(SimpleQueryObjectVO queryObject, EntityManager entityManager){
		//查询
		String sql = queryObject.toCountSql();
		Query query = entityManager.createNativeQuery(sql);
		HQLConverterUtil.setParamsByMap(queryObject.getWhereValueMap(),query);
		return ((BigInteger)query.getSingleResult()).longValue();
	}





	/**
	 * @Aouthor Guoshichang
	 * @Date 19:37 on 2018/6/15.
	 * @param valueMap 入参maps
	 * @param query
	 * @Function
	 */
	private static void setParamsByMap(Map<String, Object> valueMap,Query query){
		//设置where条件值
		valueMap.forEach((key,value)->{
			if(value.getClass().getSimpleName().endsWith("Date")){
				query.setParameter(key,(Date) value, TemporalType.TIMESTAMP);
			}else{
				query.setParameter(key,value);
			}
		});
	}

	/**
	 * @Aouthor Guoshichang
	 * @Date 17:25 on 2018/6/15.
	 * @param params
	 * @param query
	 * @Function  为sql设置参数
	 */
	private static void setParamsByObjectArray(Object[] params,Query query){
		//设置where条件值
		if(params!=null){
			for (int i = 0; i < params.length; i++) {
				Object value = params[i];
				int pos = i+1;
				if(value.getClass().getSimpleName().endsWith("Date")){
					query.setParameter(pos,(Date) value, TemporalType.TIMESTAMP);
				}else{
					query.setParameter(pos,value);
				}
			}
		}
	}






	/**
	 * @Aouthor Guoshichang
	 * @Date 19:18 on 2018/5/29.
	 * @param columnValue sql返回值类型
	 * @param field 设置值的字段
	 * @Function 根据字段类型 适配 sql返回值的类型
	 */
	private static Object bigDecimalAdapter(Object columnValue, Field field){
		//特殊字段映射
		if(columnValue!=null && columnValue.getClass().getSimpleName().endsWith("BigInteger")){
			BigInteger  value = (BigInteger)columnValue;
			String fieldType = field.getType().getSimpleName();
			switch (fieldType){
				case "double": columnValue = value.doubleValue();break;
				case "Double": columnValue = value.doubleValue(); break;
				case "int": columnValue = value.intValue(); break;
				case "Integer": columnValue = value.intValue(); break;
				case "long": columnValue = value.longValue(); break;
				case "Long": columnValue = value.longValue(); break;
				case "String": columnValue = String.valueOf( value.doubleValue()); break;
				case "BigDecimal": columnValue = new BigDecimal(value); break;
			}
		} else if (columnValue!=null && columnValue.getClass().getSimpleName().endsWith("Double") && field.getType().getSimpleName().endsWith("BigDecimal")) {
			columnValue = new BigDecimal((Double) columnValue);
		}
		return columnValue;
	}







	/**
	 * 将select部分处理
	 * @param simpleQueryObjectVO
	 * @param resultListClass
	 * @return
	 */
	private static SimpleQueryObjectVO getSelectBody(SimpleQueryObjectVO simpleQueryObjectVO,Class<?> resultListClass){
		SimpleQueryOrderBy simpleQueryOrderByAnno =resultListClass.getDeclaredAnnotation(SimpleQueryOrderBy.class);
		//加入orderBy
		if(simpleQueryOrderByAnno !=null){
			simpleQueryObjectVO.getOrderByString().append(simpleQueryOrderByAnno.value());
		}
		//加入select 体
		simpleQueryObjectVO.getSelectString().append("SELECT").append(" ");
		Field[] fields = resultListClass.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			SimpleQuerySelect simpleQuerySelectAnno=field.getDeclaredAnnotation(SimpleQuerySelect.class);
			 
			if(simpleQuerySelectAnno != null){
				//加入查询 
				if(simpleQuerySelectAnno.specialName()!=null && simpleQuerySelectAnno.specialName().length()>0){
					simpleQueryObjectVO.getSelectString().append(simpleQuerySelectAnno.specialName());
				}else{
					simpleQueryObjectVO.getSelectString().append(field.getName());
				} 
				simpleQueryObjectVO.getSelectString().append(",");
				 
				//是否需要加入groupBy
				if(simpleQuerySelectAnno.joinGoupBy()){
					if(simpleQueryObjectVO.getGroupByString().length()==0){
						simpleQueryObjectVO.getGroupByString().append(" ").append("GROUP BY").append(" ");
					}
					if(simpleQuerySelectAnno.specialName()!=null && simpleQuerySelectAnno.specialName().length()>0){
						simpleQueryObjectVO.getGroupByString().append(simpleQuerySelectAnno.specialName()).append(",");
					}else{
						simpleQueryObjectVO.getGroupByString().append(field.getName()).append(",");
					} 
				}
				//加入查询结果映射
				simpleQueryObjectVO.getSelectField().add(field.getName());
			}
			 
		}
		//处理逗号
		String selectResult = simpleQueryObjectVO.getSelectString().substring(0, simpleQueryObjectVO.getSelectString().length()-1);
		simpleQueryObjectVO.setSelectString(new StringBuffer(selectResult));
		//处理逗号
		if(simpleQueryObjectVO.getGroupByString().length()>0){
			String result = simpleQueryObjectVO.getGroupByString().substring(0, simpleQueryObjectVO.getGroupByString().length()-1);
			simpleQueryObjectVO.setGroupByString(new StringBuffer(result));
		}
		return simpleQueryObjectVO;
	}
	
	
	
	/**
	 * 将from以后部分拼装好
	 * @param simpleQueryObjectVO
	 * @param paramObject
	 * @param resultListClass
	 * @return
	 * @throws Exception
	 */
	private static SimpleQueryObjectVO getFromAndWhereBody(SimpleQueryObjectVO simpleQueryObjectVO,Object paramObject,Class<?> resultListClass)throws Exception{
		Class<?> paramObjectClass = paramObject.getClass();
		try{
			SimpleQueryOrderBy simpleQueryOrderByAnno =paramObjectClass.getDeclaredAnnotation(SimpleQueryOrderBy.class);
			//加入orderBy
			if(simpleQueryOrderByAnno !=null){
				simpleQueryObjectVO.getOrderByString().append(simpleQueryOrderByAnno.value());
			}

			SimpleQueryFrom simpleQueryFromAnno=paramObjectClass.getDeclaredAnnotation(SimpleQueryFrom.class);
			 
			//加入from部分
			simpleQueryObjectVO.getFromString().append("FROM").append(" ").append(simpleQueryFromAnno.value()).append(" ");
			String[] joins = simpleQueryFromAnno.join();
			//加入join部分
			if(joins!=null && joins.length>0){
				for (String joinStr : joins) {
					simpleQueryObjectVO.getFromString().append(" ").append(joinStr).append(" ");
				}
			}
			//加入where部分
			Field[] fields=paramObjectClass.getDeclaredFields();
			simpleQueryObjectVO.getWhereString().append("WHERE").append(" ").append("1=1").append(" ");
			for (Field field : fields) {
				field.setAccessible(true);
				SimpleQueryWhere simpleQueryWhereAnno = field.getDeclaredAnnotation(SimpleQueryWhere.class);
				if(simpleQueryWhereAnno != null){
					//将配置的字段内容加载到simpleQueryObjectVO中
					HQLConverterUtil.bindWhereValue(simpleQueryObjectVO,field,paramObject);
				}
			}
			 
		}catch(Exception e){
			e.printStackTrace();
			throw new Exception("HQLConverterUtil.getFromAndWhereBody()出错:"+e.getMessage());
		}
		return simpleQueryObjectVO;
	}
	
	
	/**
	 * 将字段中的值根据注解配置 加载到where条件中
	 * @param simpleQueryObjectVO
	 * @param field
	 * @param paramObject
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 */
	private static void bindWhereValue(SimpleQueryObjectVO simpleQueryObjectVO,Field field,Object paramObject) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException{
		SimpleQueryWhere simpleQueryWhereAnno = field.getDeclaredAnnotation(SimpleQueryWhere.class);
		//有注解 且字段有值
		if(simpleQueryWhereAnno != null && field.get(paramObject)!=null){
			//剔除List空数
			if(field.getType().getSimpleName().endsWith("List") && ((List)field.get(paramObject)).size() == 0){
				return;
			}
			//连接条件
			if(simpleQueryWhereAnno.queryType() == QueryType.AND){
				simpleQueryObjectVO.getWhereString().append(" ").append("AND").append(" ");
			}else if(simpleQueryWhereAnno.queryType() == QueryType.OR){
				simpleQueryObjectVO.getWhereString().append(" ").append("OR").append(" ");
			}
			//where 条件前部分
			if(simpleQueryWhereAnno.specialName() != null && simpleQueryWhereAnno.specialName().trim().length()>0){
				simpleQueryObjectVO.getWhereString().append(" ").append(simpleQueryWhereAnno.specialName()).append(" ");
			}else{
				simpleQueryObjectVO.getWhereString().append(" ").append(field.getName()).append(" ");
			}

			//比较符
			switch (simpleQueryWhereAnno.linkType()) {
			case EQ:
				simpleQueryObjectVO.getWhereString().append("=").append(" :").append(field.getName());
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(), field.get(paramObject));
				break;
			case LESS:
				simpleQueryObjectVO.getWhereString().append("<").append(" :").append(field.getName());
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(), field.get(paramObject));
				break;
			case LESS_EQ:
				simpleQueryObjectVO.getWhereString().append("<=").append(" :").append(field.getName());
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(), field.get(paramObject));
				break;
			case THAN:
				simpleQueryObjectVO.getWhereString().append(">").append(" :").append(field.getName());
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(), field.get(paramObject));
				break;
			case THAN_EQ:
				simpleQueryObjectVO.getWhereString().append(">=").append(" :").append(field.getName());
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(), field.get(paramObject));
				break;
			case LIKE:
				simpleQueryObjectVO.getWhereString().append("like").append(" :").append(field.getName());
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(),"%"+field.get(paramObject)+"%");
				break;
			case LIKE_START:
				simpleQueryObjectVO.getWhereString().append("like").append(" :").append(field.getName());
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(),field.get(paramObject)+"%");
				break;
			case LIKE_END:
				simpleQueryObjectVO.getWhereString().append("like").append(" :").append(field.getName());
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(),"%"+field.get(paramObject));
				break;
			case BETWEEN:
				Field startField = paramObject.getClass().getDeclaredField(simpleQueryWhereAnno.betweenStartField());
				startField.setAccessible(true);
				Field endField = paramObject.getClass().getDeclaredField(simpleQueryWhereAnno.betweenEndField());
				endField.setAccessible(true);
				if(endField.get(paramObject) == null){
					endField = startField;
				}
				simpleQueryObjectVO.getWhereString().append("BETWEEN").append(" :").append(startField.getName()).append(" ");
				simpleQueryObjectVO.getWhereString().append("AND").append(" :").append(endField.getName());
				simpleQueryObjectVO.getWhereValueMap().put(startField.getName(),startField.get(paramObject));
				simpleQueryObjectVO.getWhereValueMap().put(endField.getName(),endField.get(paramObject));
				break;
			case IN:
				simpleQueryObjectVO.getWhereString().append("IN").append(" (").append(":").append(field.getName()).append(") ");
				simpleQueryObjectVO.getWhereValueMap().put(field.getName(),field.get(paramObject));
				break;
			}
			simpleQueryObjectVO.getWhereString().append(" ");
		}
	}

}
